/*
#include <iostream>
#include <vector>
#include <cstring>
#include <iostream>
#include <cstddef>
#include <fstream>
#include <unordered_map>
#include <string>
#include <vector>
#include <buffer.h>
#include <sys/stat.h>

using namespace std;

size_t Split(const std::string& src,const std::string sep,std::vector<std::string>* array){
    int pos = 0,tmp=0;
    while(tmp < src.size()){
        pos=src.find(sep,tmp);
        // 说明找到末尾都没找到，直接放进array中
        if(pos == string::npos){
            array->push_back(src.substr(tmp));
            return array->size();
        }
        if(pos!=tmp){
            array->push_back(src.substr(tmp,pos-tmp));
        }
        tmp = pos+sep.size();
    }
    return array->size();
}
bool ReadFile(const std::string& filename,std::string* buffer){
    // 将文件以二进制形式进行读取
    std::ifstream ifs(filename,std::ios::binary);
    if(ifs.is_open() == false){
        std::cout << strerror(errno) <<std::endl;
        std::cout << "OPEN FILE: " << filename << " FAILED!" << std::endl; 
        return false;
    }
    size_t fsize =0 ;
    // 跳转读写位置到末尾
    ifs.seekg(0,ifs.end);
    // 获取当前读写位置相对于起始位置的偏移量，这个偏移量也就是文件大小
    fsize = ifs.tellg();
    // 再跳转到起始位置
    ifs.seekg(0,ifs.beg);
    // 开辟文件大小空间
    buffer->resize(fsize);
    // 将数据移入buffer中
    ifs.read(&(*buffer)[0], fsize);
    if(ifs.good()==false){
        std::cout << "READ FILE: " << filename << " FAILED!" << std::endl;
        ifs.close();
        return false;
    }
    ifs.close();
    return true;
}
bool WriteFile(const std::string& filename,const std::string& buffer){
    // 一个std::ofstream输出文件流的对象，表示可以通过ofs对象向文件写入，binary以二进制模式打开文件，且写入时不做任何格式转换
    // trunc表示将原有文件内容清空写入
    std::ofstream ofs(filename,std::ios::binary|std::ios::trunc);
    if(ofs.is_open()==false){
        std::cout << "OPEN FILE: " << filename << " FAILED!" << std::endl; 
        return false;
    }
    ofs.write(buffer.c_str(), buffer.size());
    if(ofs.good()==false){
        std::cout << "WRITE FILE: " << filename << " FAILED!" << std::endl;
        ofs.close();
        return false;
    }
    ofs.close();
    return true;
}
std::string UrlEncode(const std::string& url,bool convert_space_to_plus){
    std::string ret;
    for(auto c:url){
        // isalnum判断是否是字母或是数字
        if(c=='.' || c == '_' || c == '-' || c == '~' || isalnum(c)){
            ret += c;
            continue;
        }
        if(convert_space_to_plus && c == ' '){
            ret += '+';
            continue;
        }
        // %HH占三个字符，snprintf最后要加'\0'
        char tmp[4] = {0};
        // %是特殊字符，所以需要%%转义为%，%02X，表示两位16进制数字，不够两位则补0
        snprintf(tmp,sizeof(tmp), "%%%02X", c);
        ret+=tmp;
    }
    return ret;
}

char HEXTOI(char c){
    if(c >= '0' && c <= '9'){
        return c-'0' ;
    }else if(c >= 'a' && c <= 'z'){
        return c - 'a'+ 10;
    }
    else if(c >= 'A' && c<='Z'){
        return c - 'A'+10;
    }
    return -1;
}

std::string UrlDecode(const std::string& urlencode,bool convert_plus_to_space){
    std::string ret;
    for(int i=0;i<urlencode.size();i++){
        if(urlencode[i] == '+' && convert_plus_to_space){
            ret += ' ';
            continue;
        }
        if(urlencode[i] == '%' && (i+2) <urlencode.size()){
            char c1 = HEXTOI(urlencode[i+1]);
            char c2 = HEXTOI(urlencode[i+2]);
            char c=c1*16+c2;
            i+=2;
            ret += c;
            continue;
        }
        ret +=urlencode[i];
    }
    return ret;
}
std::unordered_map<int,std::string> _statu_msg={
    {100,  "Continue"},
    {101,  "Switching Protocol"},
    {102,  "Processing"},
    {103,  "Early Hints"},
    {200,  "OK"},
    {201,  "Created"},
    {202,  "Accepted"},
    {203,  "Non-Authoritative Information"},
    {204,  "No Content"},
    {205,  "Reset Content"},
    {206,  "Partial Content"},
    {207,  "Multi-Status"},
    {208,  "Already Reported"},
    {226,  "IM Used"},
    {300,  "Multiple Choice"},
    {301,  "Moved Permanently"},
    {302,  "Found"},
    {303,  "See Other"},
    {304,  "Not Modified"},
    {305,  "Use Proxy"},
    {306,  "unused"},
    {307,  "Temporary Redirect"},
    {308,  "Permanent Redirect"},
    {400,  "Bad Request"},
    {401,  "Unauthorized"},
    {402,  "Payment Required"},
    {403,  "Forbidden"},
    {404,  "Not Found"},
    {405,  "Method Not Allowed"},
    {406,  "Not Acceptable"},
    {407,  "Proxy Authentication Required"},
    {408,  "Request Timeout"},
    {409,  "Conflict"},
    {410,  "Gone"},
    {411,  "Length Required"},
    {412,  "Precondition Failed"},
    {413,  "Payload Too Large"},
    {414,  "URI Too Long"},
    {415,  "Unsupported Media Type"},
    {416,  "Range Not Satisfiable"},
    {417,  "Expectation Failed"},
    {418,  "I'm a teapot"},
    {421,  "Misdirected Request"},
    {422,  "Unprocessable Entity"},
    {423,  "Locked"},
    {424,  "Failed Dependency"},
    {425,  "Too Early"},
    {426,  "Upgrade Required"},
    {428,  "Precondition Required"},
    {429,  "Too Many Requests"},
    {431,  "Request Header Fields Too Large"},
    {451,  "Unavailable For Legal Reasons"},
    {501,  "Not Implemented"},
    {502,  "Bad Gateway"},
    {503,  "Service Unavailable"},
    {504,  "Gateway Timeout"},
    {505,  "HTTP Version Not Supported"},
    {506,  "Variant Also Negotiates"},
    {507,  "Insufficient Storage"},
    {508,  "Loop Detected"},
    {510,  "Not Extended"},
    {511,  "Network Authentication Required"},
};
std::unordered_map<std::string,std::string> _mime_msg = {
    {".aac",        "audio/aac"},
    {".abw",        "application/x-abiword"},
    {".arc",        "application/x-freearc"},
    {".avi",        "video/x-msvideo"},
    {".azw",        "application/vnd.amazon.ebook"},
    {".bin",        "application/octet-stream"},
    {".bmp",        "image/bmp"},
    {".bz",         "application/x-bzip"},
    {".bz2",        "application/x-bzip2"},
    {".csh",        "application/x-csh"},
    {".css",        "text/css"},
    {".csv",        "text/csv"},
    {".doc",        "application/msword"},
    {".docx",       "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
    {".eot",        "application/vnd.ms-fontobject"},
    {".epub",       "application/epub+zip"},
    {".gif",        "image/gif"},
    {".htm",        "text/html"},
    {".html",       "text/html"},
    {".ico",        "image/vnd.microsoft.icon"},
    {".ics",        "text/calendar"},
    {".jar",        "application/java-archive"},
    {".jpeg",       "image/jpeg"},
    {".jpg",        "image/jpeg"},
    {".js",         "text/javascript"},
    {".json",       "application/json"},
    {".jsonld",     "application/ld+json"},
    {".mid",        "audio/midi"},
    {".midi",       "audio/x-midi"},
    {".mjs",        "text/javascript"},
    {".mp3",        "audio/mpeg"},
    {".mpeg",       "video/mpeg"},
    {".mpkg",       "application/vnd.apple.installer+xml"},
    {".odp",        "application/vnd.oasis.opendocument.presentation"},
    {".ods",        "application/vnd.oasis.opendocument.spreadsheet"},
    {".odt",        "application/vnd.oasis.opendocument.text"},
    {".oga",        "audio/ogg"},
    {".ogv",        "video/ogg"},
    {".ogx",        "application/ogg"},
    {".otf",        "font/otf"},
    {".png",        "image/png"},
    {".pdf",        "application/pdf"},
    {".ppt",        "application/vnd.ms-powerpoint"},
    {".pptx",       "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
    {".rar",        "application/x-rar-compressed"},
    {".rtf",        "application/rtf"},
    {".sh",         "application/x-sh"},
    {".svg",        "image/svg+xml"},
    {".swf",        "application/x-shockwave-flash"},
    {".tar",        "application/x-tar"},
    {".tif",        "image/tiff"},
    {".tiff",       "image/tiff"},
    {".ttf",        "font/ttf"},
    {".txt",        "text/plain"},
    {".vsd",        "application/vnd.visio"},
    {".wav",        "audio/wav"},
    {".weba",       "audio/webm"},
    {".webm",       "video/webm"},
    {".webp",       "image/webp"},
    {".woff",       "font/woff"},
    {".woff2",      "font/woff2"},
    {".xhtml",      "application/xhtml+xml"},
    {".xls",        "application/vnd.ms-excel"},
    {".xlsx",       "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
    {".xml",        "application/xml"},
    {".xul",        "application/vnd.mozilla.xul+xml"},
    {".zip",        "application/zip"},
    {".3gp",        "video/3gpp"},
    {".3g2",        "video/3gpp2"},
    {".7z",         "application/x-7z-compressed"},
};
std::string StatuDesc(int status){
    auto iter = _statu_msg.find(status);
    if(iter == _statu_msg.end()){
        return "UNKNOWN STATUS";
    }
    return iter->second;
}
// 根据文件名后缀获取mime
std::string Getmime(const std::string& filename){
    int pos = filename.rfind('.');
    std::string str = filename.substr(pos);
    auto iter = _mime_msg.find(str);
    if(iter == _mime_msg.end()){
        return "UNKNOWN MIME";
    }
    return iter->second;
}
bool IsDirectory(const std::string& filename){
    // stat结构体定义了文件的各种属性，如大小权限类型等
    struct stat st;
    // stat获取文件元数据，也就是属性
    int ret = stat(filename.c_str(),&st);
    if(ret < 0){
        return false;
    }
    // 是一个宏，来判断这个文件模式是否是目录
    return S_ISDIR(st.st_mode);
}
// 判断一个文件是否是一个普通文件
bool IsRegular(const std::string& filename){
     // stat结构体定义了文件的各种属性，如大小权限类型等
     struct stat st;
     // stat获取文件元数据，也就是属性
     int ret = stat(filename.c_str(),&st);
     if(ret < 0){
         return false;
     }
     // 是一个宏，来判断这个文件模式是否是目录
     return S_ISREG(st.st_mode);
}
bool ValidPath(const std::string& path){
    int count = 0;
    // 用来存储每次截取的字符串内容
    std::vector<std::string> subpath ;
    Split(path, "/", &subpath);
    for(auto str: subpath){
        if(str == ".."){
            count--;
            if(count <0){
                return false;
            }
            continue;
        }
        count++;
    }
    return true;
}
int main(){
    // "" ," " 
    // string str("");
    // string sep(",");
    // vector<string> array;
    // size_t num = Split(str, sep, &array);
    // for(auto c:array){
    //     cout << c << endl;
    // }
    // cout << num << endl;
    // string str;
    // bool b = ReadFile("/home/lyt/linux-study/HttpServer/src/http/src/buffer.cpp",&str);
    // str.clear();
    // str+="asdfasdf";
    // WriteFile("/home/lyt/linux-study/HttpServer/src/http/src/buff.cpp", str);
    // string str("C++ ");
    // string ret = UrlEncode(str, true);
    // cout << ret << endl;
    // string str("C%2B%2B");
    // string str1 = UrlDecode(str, false);
    // cout << '['<< str1 << ']'<< endl;
    // str = "C%2B%2B+";
    // str1 = UrlDecode(str, false);
    // cout << '['<< str1 << ']'<< endl;
    // str = "C%2B%2B+";
    // str1 = UrlDecode(str, true);
    // cout << '['<< str1 << ']'<< endl;
    // string str = StatuDesc(200);
    // cout << str << endl;
    // str = Getmime("asdf.css");
    // cout << str << endl;
    // bool b = IsDirectory("/home/lyt/linux-study/HttpServer/src/http/src");
    // cout << b <<endl;
    // b=IsRegular("/home/lyt/linux-study/HttpServer/src/http/src");
    // cout << b <<endl;
    // string str("/../test");
    // cout << ValidPath(str);
    // str="/test";
    // cout << ValidPath(str);
    // str="/test/../../";
    // cout << ValidPath(str);
    // str="/test/sdf/../../../";
    // cout << ValidPath(str);
    return 0;
}
    */